package com.turman.networkdemo

import androidx.collection.SimpleArrayMap
import com.google.gson.Gson
import okhttp3.*
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File
import java.io.IOException
import java.util.concurrent.TimeUnit

class OkHttpApi:HttpApi {
    companion object {
        private const val TAG="OkHttpApi"
    }

    private val baseURL = "http://api.qingyunke.com/"

    //保存请求，用于取消请求的map
    private val callMap = SimpleArrayMap<Any,Call>()

    private val mClient:OkHttpClient = OkHttpClient.Builder()
        .callTimeout(10,TimeUnit.SECONDS)
        .connectTimeout(10,TimeUnit.SECONDS)
        .readTimeout(10,TimeUnit.SECONDS)
        .writeTimeout(10,TimeUnit.SECONDS)
        .retryOnConnectionFailure(true)
        .followRedirects(false)  //不支持重定向
        .cache(Cache(File("sdcard/cache","okhttp"),1024))  //cache设置
//        .cookieJar(CookieJar.NO_COOKIES)
        .cookieJar(LocalCookieJar())  //cookie缓存策略
        .addNetworkInterceptor(KtHttpLogInterceptor{
            logLevel(KtHttpLogInterceptor.LogLevel.BODY)
        })
        .build()

    override fun get(params: Map<String, Any>, path: String, callback: IHttpCallback) {
        val urlBuilder = "$baseURL$path".toHttpUrl().newBuilder()
        params.forEach{
            urlBuilder.addEncodedQueryParameter(it.key,it.value.toString())
        }
        val request:Request = Request.Builder()
            .get()
            .tag(params) //添加tag 用于取消请求
            .url(urlBuilder.build())
            .cacheControl(CacheControl.FORCE_NETWORK)
            .build()

        mClient.newCall(request).let { callMap.put(params,it) }?.enqueue(object:Callback{
            override fun onFailure(call: Call, e: IOException) {
                callback.onFailed(e.message)
            }

            override fun onResponse(call: Call, response: Response) {
                callback.onSuccess(response)
            }

        })
    }

    override fun getSync(params: Map<String, Any>, path: String): Any? {
        val urlBuilder = "$baseURL$path".toHttpUrl().newBuilder()
        params.forEach{
            urlBuilder.addEncodedQueryParameter(it.key,it.value.toString())
        }
        val request:Request = Request.Builder()
            .get()
            .tag(params)
            .url(urlBuilder.build())
            .cacheControl(CacheControl.FORCE_NETWORK)
            .build()

        return mClient.newCall(request).let { callMap.put(params,it) }?.execute()
    }

    override fun post(body: Any, path: String, callback: IHttpCallback) {
        val url = "$baseURL$path"
        val request:Request = Request.Builder()
            .post(Gson().toJson(body).toRequestBody())
            .tag(body)
            .url(url)
            .build()

        mClient.newCall(request).let { callMap.put(body,it) }?.enqueue(object:Callback{
            override fun onFailure(call: Call, e: IOException) {
                callback.onFailed(e.message)
            }

            override fun onResponse(call: Call, response: Response) {
                callback.onSuccess(response)
            }
        })
    }

    override fun postSync(body: Any, path: String): Any? {
        val url = "$baseURL$path"
        val request:Request = Request.Builder()
            .post(Gson().toJson(body).toRequestBody())
            .tag(body)
            .url(url)
            .build()

        return mClient.newCall(request).let { callMap.put(body,it) }?.execute()
    }

    override fun cancelRequest(tag: Any) {
        callMap.get(tag)?.cancel()
    }

    override fun cancelAllRequest() {
        for (i:Int in 0 until callMap.size()) {
            callMap.get(callMap.keyAt(i))?.cancel()
        }
    }
}